using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using Common.Core;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity.Configuration;

namespace Common.Unity.Extensions.PropertyMapper
{
	class PropertyMappingExpressionPropertySetterInfo : IPropertySetterInfo
	{
		readonly PropertyMappingExpressionContext sourceContext, targetContext;
		readonly Type converterType;

		public PropertyMappingExpressionPropertySetterInfo( PropertyMappingExpressionContext sourceContext, PropertyMappingExpressionContext targetContext, Type converterType )
		{
			this.sourceContext = sourceContext;
			this.targetContext = targetContext;
			this.converterType = converterType;
		}

		protected PropertyMappingExpressionContext SourceContext
		{
			get { return sourceContext; }
		}

		protected PropertyMappingExpressionContext TargetContext
		{
			get { return targetContext; }
		}

		protected Type Converter
		{
			get { return converterType; }
		}

		protected virtual void Set( IBuilderContext context, object instance, object buildKey )
		{
			object 
				ensured = ConversionHelper.CheckForConversion( SourceContext.Value, TargetContext.Property, Converter ),
				current = TargetContext.Property.GetValue( TargetContext.Container, CommonBindingFlags.AllProperties, null, TargetContext.Index, CultureInfo.CurrentCulture );
			if ( !Equals( ensured, current ) )
			{
				TargetContext.Property.SetValue( TargetContext.Container, ensured, TargetContext.Index );
			}
		}

		void IPropertySetterInfo.Set( IBuilderContext context, object instance, object buildKey )
		{
			Set( context, instance, buildKey );
		}
	}
}